﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions.Readers;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions;
using TSU.FAMC.ComputerEngineering.Classes.Circuits;
using TSU.FAMC.ComputerEngineering.Classes.Circuits.Readers;
using TSU.FAMC.ComputerEngineering.Classes.OrandTrees;
using TSU.FAMC.ComputerEngineering.Classes.OrandTrees.Readers;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // test 1
            var systemOriginalStr = ".type fr\r\n.mask 3|3 4|0|3\r\n.i 6\r\n.o 7\r\n.p 28\r\n000000 0101000\r\n100000 0101001\r\n010000 0101010\r\n--1000 1010000\r\n100001 0101001\r\n0-0001 0101000\r\n110001 0101011\r\n--1001 1010000\r\n110011 0101011\r\n100011 0101001\r\n010011 0101100\r\n--1011 1010000\r\n010100 0101100\r\n110100 0101011\r\n000100 0110000\r\n--1100 1010000\r\n010010 0101010\r\n-00010 0101000\r\n110010 0101101\r\n--1010 1010000\r\n110101 0101101\r\n010101 0101010\r\n100101 0101110\r\n--1101 1010000\r\n100110 0101110\r\n110110 0101101\r\n000110 1001000\r\n--1110 1010000\r\n";
            var systemMinEachStr = ".type fd\r\n.i 6\r\n.o 7\r\n.p 25\r\n0--11- 1000000\r\n--1--- 1010000\r\n--00-- 0101000\r\n1-0--- 0100000\r\n--0-0- 0100000\r\n-0-100 0010000\r\n--0-1- 0001000\r\n-10--- 0001000\r\n--0--1 0001000\r\n0-0-11 0000100\r\n0101-0 0000100\r\n110-10 0000100\r\n1-01-1 0000100\r\n1-011- 0000100\r\n-001-1 0000100\r\n1-0100 0000010\r\n0-01-1 0000010\r\n0100-0 0000010\r\n1100-1 0000010\r\n110-11 0000010\r\n010-10 0000010\r\n1001-- 0000010\r\n1-000- 0000001\r\n1-00-1 0000001\r\n110--- 0000001\r\n.e";
            var systemTestStr = ".type fd\r\n.i 6\r\n.o 7\r\n.p 24\r\n--1--- 1000000\r\n0--11- 1000000\r\n--00-- 0100000\r\n--0-0- 0100000\r\n1-0--- 0100000\r\n--1--- 0010000\r\n00-10- 0010000\r\n--00-- 0001000\r\n-10--- 0001000\r\n1-0--- 0001000\r\n--0-1- 0001000\r\n0-0-11 0000100\r\n0101-0 0000100\r\n1100-0 0000100\r\n1-01-1 0000100\r\n1-011- 0000100\r\n0100-0 0000010\r\n0-01-1 0000010\r\n1100-1 0000010\r\n110-00 0000010\r\n1001-- 0000010\r\n1-000- 0000001\r\n1-0-11 0000001\r\n110--- 0000001\r\n.e";

            // test 2
            var systemOriginalStr2 = ".type fr\r\n.mask 2|3 2|0|3\r\n.i 5\r\n.o 5\r\n.p 24\r\n00000 00000\r\n01000 00001\r\n10000 00001\r\n11000 00001\r\n00001 00000\r\n01001 00010\r\n10001 00010\r\n11001 00010\r\n00010 00001\r\n01010 00011\r\n10010 00011\r\n11010 00011\r\n00011 00100\r\n01011 01011\r\n10011 10011\r\n11011 11011\r\n00100 00101\r\n01100 00100\r\n10100 00100\r\n11100 00100\r\n00101 00000\r\n01101 00101\r\n10101 00101\r\n11101 00101";
            var systemMinEachStr2 = ".type fd\r\n.i 5\r\n.o 5\r\n.p 16\r\n1--11 10000\r\n-1-11 01000\r\n00-11 00100\r\n-11-- 00100\r\n1-1-- 00100\r\n--1-0 00100\r\n1-0-1 00010\r\n1--1- 00011\r\n-10-1 00010\r\n-1-1- 00011\r\n001-0 00001\r\n1-1-1 00001\r\n-11-1 00001\r\n1-0-0 00001\r\n-10-0 00001\r\n---10 00001\r\n.e";
            var systemTestStr2 = ".type fd\r\n.i 5\r\n.o 5\r\n.p 18\r\n1--11 10000\r\n-1-11 01000\r\n00-11 00100\r\n--1-0 00100\r\n-11-- 00100\r\n1-1-- 00100\r\n-10-1 00010\r\n1-0-1 00010\r\n-1-1- 00010\r\n1--1- 00010\r\n-10-0 00001\r\n1-0-0 00001\r\n---10 00001\r\n-1-1- 00001\r\n1--1- 00001\r\n001-0 00001\r\n-11-1 00001\r\n1-1-1 00001\r\n.e";


            // readers
            var readerFR = new BooleanSystemReaderPlafr();
            var readerFD = new BooleanSystemReaderPlafd();


            // TEST 1

            // original system
            var systemOriginal = new BooleanSystem();
            readerFR.System = systemOriginal;
            readerFR.Input = systemOriginalStr;
            readerFR.Read();

            // minimized system in format FD (only Domain1)
            var systemMnimized = new BooleanSystem();
            readerFD.System = systemMnimized;
            readerFD.Input = systemMinEachStr;
            readerFD.Read();

            // copying Domain0 from original system
            for (var i = 0; i < systemOriginal.Functions.Count; i++)
            {
                systemMnimized.Functions[i].Domain0 = systemOriginal.Functions[i].Domain0;
            }

            // checking whether minimized system is realization of original one
            if (!systemMnimized.IsRealizationOf(systemOriginal))
            {
                MessageBox.Show("Ошибка! Моя минимизированная система не реализует исходную!");
                return;
            }

            // testing minimized system irredundency
            if (!systemMnimized.TestIrredundency())
            {
                MessageBox.Show("Ошибка! Моя минимизированная система не является безызбыточной!");
                return;
            }



            // test system in FD format (only Domain1)
            var systemTest = new BooleanSystem();
            readerFD.System = systemTest;
            readerFD.Input = systemTestStr;
            readerFD.Read();

            // copying Domain0 from original system
            for (var i = 0; i < systemOriginal.Functions.Count; i++)
            {
                systemTest.Functions[i].Domain0 = systemOriginal.Functions[i].Domain0;
            }

            // checking whether test system is realization of original one
            if (!systemTest.IsRealizationOf(systemOriginal))
            {
                MessageBox.Show("Ошибка! Тестовая система не реализует исходную!");
                return;
            }

            // testing system irredundency
            if (!systemTest.TestIrredundency())
            {
                MessageBox.Show("Ошибка! Тестовая система не является безызбыточной!");
                return;
            }



            // TEST 2


            // original system
            var systemOriginal2 = new BooleanSystem();
            readerFR.System = systemOriginal2;
            readerFR.Input = systemOriginalStr2;
            readerFR.Read();

            // minimized system in format FD (only Domain1)
            var systemMnimized2 = new BooleanSystem();
            readerFD.System = systemMnimized2;
            readerFD.Input = systemMinEachStr2;
            readerFD.Read();

            // copying Domain0 from original system
            for (var i = 0; i < systemOriginal2.Functions.Count; i++)
            {
                systemMnimized2.Functions[i].Domain0 = systemOriginal2.Functions[i].Domain0;
            }

            // checking whether minimized system is realization of original one
            if (!systemMnimized2.IsRealizationOf(systemOriginal2))
            {
                MessageBox.Show("Ошибка! Моя минимизированная система #2 не реализует исходную!");
                return;
            }

            // testing minimized system irredundency
            if (!systemMnimized2.TestIrredundency())
            {
                MessageBox.Show("Ошибка! Моя минимизированная система #2 не является безызбыточной!");
                return;
            }



            // test system in FD format (only Domain1)
            var systemTest2 = new BooleanSystem();
            readerFD.System = systemTest2;
            readerFD.Input = systemTestStr2;
            readerFD.Read();

            // copying Domain0 from original system
            for (var i = 0; i < systemOriginal2.Functions.Count; i++)
            {
                systemTest2.Functions[i].Domain0 = systemOriginal2.Functions[i].Domain0;
            }

            // checking whether test system is realization of original one
            if (!systemTest2.IsRealizationOf(systemOriginal2))
            {
                MessageBox.Show("Ошибка! Тестовая система #2 не реализует исходную!");
                return;
            }

            // testing system irredundency
            if (!systemTest2.TestIrredundency())
            {
                MessageBox.Show("Ошибка! Тестовая система #2 не является безызбыточной!");
                return;
            }



            MessageBox.Show("Тест прошел успешно!");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // system string
            var systemOriginalStr = ".type fr\r\n.i 4\r\n.o 3\r\n.p 11\r\n-000 000\r\n1100 000\r\n0100 001\r\n0-01 101\r\n1101 000\r\n1001 110\r\n1-10 110\r\n0010 101\r\n0110 111\r\n0-11 111\r\n1111 110\r\n";
            var systemMinimizedStr = ".type fd\r\n.i 4\r\n.o 3\r\n.p 9\r\n-0-1 100\r\n0--1 101\r\n--1- 100\r\n10-1 010\r\n1-1- 010\r\n-11- 010\r\n--11 010\r\n01-- 001\r\n0-1- 001\r\n.e";

            // systems
            var systemOriginal = new BooleanSystem();
            var systemMinimized = new BooleanSystem();

            // reding systems
            var readerFR = new BooleanSystemReaderPlafr();
            var readerFD = new BooleanSystemReaderPlafd();

            readerFR.Input = systemOriginalStr;
            readerFR.System = systemOriginal;
            readerFR.Read();

            readerFD.Input = systemMinimizedStr;
            readerFD.System = systemMinimized;
            readerFD.Read();

            // setting Domain0 to minimized system because of FD format data loose
            for (var i = 0; i < systemOriginal.Functions.Count; i++)
            {
                systemMinimized.Functions[i].Domain0 = systemOriginal.Functions[i].Domain0;
            }

            // circuit string
            var circuitStr = "# 4 inputs\r\n# 3 outputs\r\n# 8 inverters\r\n# 17 gates (17 NANDs)\r\nINPUT(g0)\r\nINPUT(g1)\r\nINPUT(g2)\r\nINPUT(g3)\r\nOUTPUT(g4)\r\nOUTPUT(g5)\r\nOUTPUT(g6)\r\ng7 = NOT(g0)\r\ng8 = NOT(g1)\r\ng9 = NOT(g2)\r\ng14 = NOT(g13)\r\ng16 = NOT(g15)\r\ng22 = NOT(g21)\r\ng24 = NOT(g23)\r\ng29 = NOT(g28)\r\ng4 = NAND(g9, g14)\r\ng11 = NAND(g8, g3)\r\ng12 = NAND(g7, g3)\r\ng13 = NAND(g11, g12)\r\ng5 = NAND(g24, g22)\r\ng15 = NAND(g0, g8)\r\ng17 = NAND(g3, g16)\r\ng18 = NAND(g0, g2)\r\ng19 = NAND(g1, g2)\r\ng20 = NAND(g2, g3)\r\ng21 = NAND(g17, g18)\r\ng23 = NAND(g19, g20)\r\ng6 = NAND(g27, g29)\r\ng25 = NAND(g7, g3)\r\ng26 = NAND(g7, g1)\r\ng27 = NAND(g7, g2)\r\ng28 = NAND(g25, g26)";

            // circuit
            var circuit = new Circuit();

            // building circuit
            var readerCircuit = new CircuitReaderPlain();
            readerCircuit.Input = circuitStr;
            readerCircuit.Read();
            circuit = readerCircuit.Circuit;

            // building ORANDTree
            var tree = new OrandTree();

            // reading tree from circuit
            var readerORANDTree = new OrandTreeReaderCircuit();
            readerORANDTree.Input = circuit;
            readerORANDTree.Read();
            tree = readerORANDTree.Tree;

            // tree system
            var treeSystem = new BooleanSystem();

            // reading system from ORANDTree
            var readerSytemFromORANDTree = new BooleanSystemReaderOrandTree();
            readerSytemFromORANDTree.Input = tree;
            readerSytemFromORANDTree.System = treeSystem;
            readerSytemFromORANDTree.Read();

            // setting Domain0 to tree system because circuit represents only Domain1
            for (var i = 0; i < systemOriginal.Functions.Count; i++)
            {
                treeSystem.Functions[i].Domain0 = systemOriginal.Functions[i].Domain0;
            }

            // checking tree system
            if (!treeSystem.IsRealizationOf(systemMinimized) || !systemMinimized.IsRealizationOf(treeSystem))
            {
                MessageBox.Show("Ошибка верификации с минимизированной системой! Схема построена неверно!");
                return;
            }

            if (!treeSystem.IsRealizationOf(systemOriginal))
            {
                MessageBox.Show("Ошибка верификации с минимизированной системой! Схема построена неверно!");
                return;
            }

            MessageBox.Show("Схема построена верно.");
        }
    }
}
